package com.data.permission.rule;


import com.data.permission.rule.dto.RuleConditionDTO;
import com.data.permission.rule.dto.RuleInfoDTO;
import com.data.permission.transf.ClientConnectPool;
import com.data.permission.transf.ClientListener;
import com.data.permission.transf.DataPermissionsService;
import com.data.permission.transf.ServiceInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.thrift.protocol.TProtocol;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.locks.ReentrantReadWriteLock;

@Component
@Slf4j
public class DataRuleInfoComponent {

    private static final ReentrantReadWriteLock ruleLock = new ReentrantReadWriteLock();
    private static final ReentrantReadWriteLock.ReadLock ruleReaderLock = ruleLock.readLock();
    private static final ReentrantReadWriteLock.WriteLock ruleWriteLock = ruleLock.writeLock();

    private static final ReentrantReadWriteLock conditionLock = new ReentrantReadWriteLock();
    private static final ReentrantReadWriteLock.ReadLock conditionReaderLock = conditionLock.readLock();
    private static final ReentrantReadWriteLock.WriteLock conditionWriteLock = conditionLock.writeLock();

    private Map<String, RuleInfoDTO> ruleInfoMap = null;

    private Map<String, RuleConditionDTO> conditionMap = null;

    @Autowired
    private ClientConnectPool clientConnectPool;

    /**
     * 刷新规则
     */
    public void flushRules() {
        ServiceInfo serviceInfo = ClientListener.roundServiceInfo();
        TProtocol protocol = clientConnectPool.getProtocol(serviceInfo);

        //参数对象赋值
        if (null == protocol) {
                /*未能获取到protocol，遍历获取*/
            Map<String, ServiceInfo> serviceInfoMap = ClientListener.getServiceInfoMap();
            Iterator<String> iterator = serviceInfoMap.keySet().iterator();
            while (iterator.hasNext()) {
                serviceInfo = serviceInfoMap.get(iterator.next());
                protocol = clientConnectPool.getProtocol(serviceInfo);
                if (null != protocol) {
                    break;
                }
            }
            if (null == protocol) {
                throw new RuntimeException("未能获取到服务通讯protocal");
            }
        }
        DataPermissionsService.Client client = new DataPermissionsService.Client(protocol);
        Map<String, RuleInfoDTO> oldRuleInfoMap = ruleInfoMap;
        try {

            ruleWriteLock.lock();
            ruleInfoMap = client.flushRuleInfo();
        } catch (Exception e) {
            log.info("刷新规则列表异常:{}", e);
            ruleInfoMap = oldRuleInfoMap;
        } finally {
            ruleWriteLock.unlock();
            clientConnectPool.returnProtocol(serviceInfo, protocol);
        }
    }

    /**
     * 刷新条件
     */
    public void flushConditions() {
        ServiceInfo serviceInfo = ClientListener.roundServiceInfo();
        TProtocol protocol = clientConnectPool.getProtocol(serviceInfo);

        //参数对象赋值
        if (null == protocol) {
                /*未能获取到protocol，遍历获取*/
            Map<String, ServiceInfo> serviceInfoMap = ClientListener.getServiceInfoMap();
            Iterator<String> iterator = serviceInfoMap.keySet().iterator();
            while (iterator.hasNext()) {
                serviceInfo = serviceInfoMap.get(iterator.next());
                protocol = clientConnectPool.getProtocol(serviceInfo);
                if (null != protocol) {
                    break;
                }
            }
            if (null == protocol) {
                throw new RuntimeException("未能获取到服务通讯protocal");
            }
        }
        DataPermissionsService.Client client = new DataPermissionsService.Client(protocol);
        Map<String, RuleConditionDTO> oldConditionMap = conditionMap;
        try {
            conditionWriteLock.lock();
            conditionMap = client.flushConditionMap();
        } catch (Exception e) {
            log.info("刷新规则列表异常:{}", e);
            conditionMap = oldConditionMap;
        } finally {
            conditionWriteLock.unlock();
            clientConnectPool.returnProtocol(serviceInfo, protocol);
        }
    }

    /**
     * 获取规则对象
     *
     * @return
     */
    public Map<String, RuleInfoDTO> getRuleInfoMap() {
        try {
            ruleReaderLock.lock();
            return ruleInfoMap;
        } finally {
            ruleReaderLock.unlock();
        }
    }

    /**
     * 获取condition（条件）对象
     *
     * @return
     */
    public Map<String, RuleConditionDTO> getConditionMap() {
        try {
            conditionReaderLock.lock();
            return conditionMap;
        } finally {
            conditionReaderLock.unlock();
        }
    }

}